home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2001 May / SGI Freeware 2001 May - Disc 1.iso / dist / fw_ispell.idb / usr / freeware / bin / findaffix.z / findaffix (.txt)
Microsoft Windows Help File Content  |  2000-01-25  |  10KB  |  238 lines

  1. : Use /bin/sh
  2. # $Id: findaffix.X,v 1.15 1994/01/25 07:11:29 geoff Exp $
  3. # Copyright 1992, 1993, Geoff Kuenning, Granada Hills, CA
  4. # All rights reserved.
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions
  7. # are met:
  8. # 1. Redistributions of source code must retain the above copyright
  9. #    notice, this list of conditions and the following disclaimer.
  10. # 2. Redistributions in binary form must reproduce the above copyright
  11. #    notice, this list of conditions and the following disclaimer in the
  12. #    documentation and/or other materials provided with the distribution.
  13. # 3. All modifications to the source code must be clearly marked as
  14. #    such.  Binary redistributions based on modified source code
  15. #    must be clearly marked as modified versions in the documentation
  16. #    and/or other materials provided with the distribution.
  17. # 4. All advertising materials mentioning features or use of this software
  18. #    must display the following acknowledgment:
  19. #      This product includes software developed by Geoff Kuenning and
  20. #      other unpaid contributors.
  21. # 5. The name of Geoff Kuenning may not be used to endorse or promote
  22. #    products derived from this software without specific prior
  23. #    written permission.
  24. # THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
  25. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. # ARE DISCLAIMED.  IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
  28. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34. # SUCH DAMAGE.
  35. #    Find possible affixes for use with ispell
  36. #    Usage:
  37. #    findaffix [-p | -s] [-f] [-c] [-m min] [-M max] [-e elim] [-l low] \
  38. #      [-t tabchar] [files]
  39. #    Each common prefix (-p) or suffix (-s, default) is presented, along
  40. #    with statistics to indicate how useful such an affix might be in
  41. #    reducing the size of the input file.  Only those affixes which
  42. #    produce a legal root (one found in the original input) are reported.
  43. #    If the "-c" option is not given, the output lines are in the
  44. #    following format:
  45. #        strip/add/count/bytes
  46. #    where "strip" is the string that should be stripped from a root
  47. #    word before adding the affix, "add" is the affix to be added, "count"
  48. #    is a count of the number of times that this "strip/add" combination
  49. #    appears, and "bytes" is an estimate of the number of bytes that
  50. #    will be saved in the raw dictionary file if this combination is
  51. #    added to the affix file.  The field separator in the output will
  52. #    normally be the tab character specified by the "-t" switch;  the
  53. #    default is a slash ("/").
  54. #    If the "-c" ("clean output") option is given, the appearance of
  55. #    the output is made cleaner by changing it to:
  56. #        -strip+add<tab>count<tab>bytes
  57. #    where "strip," "add," "count," and "bytes" are as before, and "<tab>"
  58. #    represents the ASCII tab character.
  59. #    The method used to generate possible affixes will also generate
  60. #    longer affixes which have common headers or trailers.  For example,
  61. #    the two words "moth" and "mother" will generate not only the obvious
  62. #    substition "+er" but also "-h+her" and "-th+ther" (and possibly
  63. #    even longer ones, depending on the value of "min").  To prevent
  64. #    cluttering the output with such affixes, any affix pair that shares
  65. #    a common header (or, for prefixes, trailer) string longer than
  66. #    "elim" characters (default 1) will be suppressed.  You may want to
  67. #    set "elim" to a value greater than 1 if your language has string
  68. #    characters;  usually the need for this parameter will become obvious
  69. #    when you examine the output of your findaffix run.
  70. #    Normally, the output is sorted on the "bytes" field.  If the "-f"
  71. #    flag is given, the output is sorted according to the "count" field.
  72. #    No affix longer than "max" characters (default 8) will be reported.
  73. #    Smaller values of "max" will make the script run faster.
  74. #    Affixes which appear fewer than "low" times (default 10) are
  75. #    suppressed.  This significantly reduces the size of the output file.
  76. #    Affixes which generate stems shorter than "min" characters (default 3)
  77. #    are suppressed.  (A stem is the word after the "strip" string has
  78. #    been removed, and before the "add" string has been added.)  This
  79. #    reduces both the running time and the size of the output file.  "Min"
  80. #    should only be set to 1 if you have a *lot* of free time and disk
  81. #    space.
  82. #    The script requires a non-blank field-separator character for internal
  83. #    use.  Normally, this character is a slash ("/"), but if the slash
  84. #    appears as a character in the input word list, a different character
  85. #    can be specified with the "-t" switch.
  86. #    If the input files are ispell dictionaries, they should be expanded
  87. #    before being fed to this script.
  88. #    If the input files contains characters other than [A-Za-z], they
  89. #    should be translated to lowercase before being fed to this script.
  90. # $Log: findaffix.X,v $
  91. # Revision 1.15  1994/01/25  07:11:29  geoff
  92. # Get rid of all old RCS log lines in preparation for the 3.1 release.
  93. TDIR=${TMPDIR-/usr/tmp}
  94. TMP=${TDIR}/faff$$
  95. SORTTMP="-T ${TDIR}"            # !!SORTTMP!!
  96. USAGE='Usage:  findaffix [-p | -s] [-f] [-c] [-e elim] [-m min] [-M max] [-l low] [-t tabch] [files]'
  97. LOOP='
  98.     i = len - maxlim + 1
  99.     if (i < minstem + 1)
  100.     i = minstem + 1
  101.     for (  ;  i <= len;  i++)
  102.     print substr ($0, 1, i - 1) tabch substr ($0, i) tabch len
  103.     print $0 tabch tabch len'
  104. ELIM='$1!=$2 \
  105.     {
  106.     if (substr ($1, 1, elimlen) != substr ($2, 1, elimlen))
  107.     print
  108.     }'
  109. maxlim=8
  110. minstem=3
  111. elimlen=1
  112. lowcount=10
  113. cleanout=no
  114. finalsortopts='+3rn -4 +2rn -3 +1 -2 +0 -1'
  115. tabch=/
  116. while :
  117.     case "$1" in
  118.         LOOP='
  119.         lim = len - minstem
  120.         if (lim > maxlim)
  121.             lim = maxlim
  122.         for (i = 1;  i <= lim;  i++)
  123.             print substr ($0, i + 1) tabch substr ($0, 1, i) tabch len
  124.         print $0 tabch tabch len'
  125.         ELIM='$1!=$2 \
  126.         if (substr ($1, length ($1), elimlen) \
  127.           != substr ($2, length ($2), elimlen))
  128.             print
  129.         shift
  130.         ;;
  131.         shift
  132.         ;;
  133.         finalsortopts='+2rn -3 +3rn -4 +1 -2 +0 -1'
  134.         shift
  135.         ;;
  136.         cleanout=yes
  137.         shift
  138.         ;;
  139.         elimlen=$2
  140.         shift; shift
  141.         ;;
  142.         minstem=$2
  143.         shift; shift
  144.         ;;
  145.         maxlim=$2
  146.         shift; shift
  147.         ;;
  148.         lowcount=$2
  149.         shift; shift
  150.         ;;
  151.         tabch="$2"
  152.         shift; shift
  153.         ;;
  154.         echo "$USAGE" 1>&2
  155.         exit 1
  156.         ;;
  157.         break
  158.         ;;
  159.     esac
  160. trap "/bin/rm -f ${TMP}*; exit 1" 1 2 15
  161. trap "/bin/rm -f ${TMP}*; exit 0" 13
  162. # We are ready to do the work.  First, we collect all input, translate it
  163. # to lowercase, sort it (dropping duplications), and save it for later.
  164. if [ $# -ne 0 ]
  165.     cat "$@" | tr '[A-Z]' '[a-z]'
  166.     tr '[A-Z]' '[a-z]'
  167.   | sort -u $SORTTMP > ${TMP}a
  168. # Now the monstrous pipeline.  The awk command produces several lines for
  169. # each input word.  Each line contains a possible stem (first field),
  170. # a possible affix, and the length of the original word.  The loop which
  171. # does this was placed into the LOOP variable by the code above (q.v.).
  172. # The first sort puts this output into an order appropriate for feeding
  173. # to 'join'.  The join command then combines stems and affixes, and for
  174. # each puts out an affix to strip, an affix to add, and the length of
  175. # the word before and after modification.
  176. # From here on out the job is relatively easy.  The second 'awk' gets rid
  177. # of lines that have the same strip and add affixes, and also eliminates
  178. # lines where the strip and add affix have a common leading (for suffixes)
  179. # or trailing (for prefixes) substring, or where the strip affix is longer
  180. # than the add affix (this is all done by the $ELIM variable, which is also
  181. # set up by the code above.  The second sort collects identical affixes;
  182. # the third 'awk' functions like 'uniq -c', replacing duplicate affixes
  183. # with a count and summing the estimate of bytes saved.  It also eliminates
  184. # any affixes which appear less frequently than the minimum ("lowcount").
  185. # Finally, the third sort ($finalsortopts) rearranges the list in the chosen
  186. # sort order.
  187. awk "BEGIN{minstem=$minstem; maxlim=$maxlim; tabch="'"'"$tabch"'"}
  188.     {
  189.     len = length ($0)
  190.     if (len < 2)
  191.     next
  192.     '"$LOOP"'
  193.     }' < ${TMP}a \
  194.   | sort "-t$tabch" +0 -1 +1 $SORTTMP -o ${TMP}a
  195. join "-t$tabch" -o 1.2 2.2 2.3 ${TMP}a ${TMP}a \
  196.   | awk "-F$tabch" "BEGIN{elimlen=$elimlen}$ELIM" \
  197.   | sort "-t$tabch" +1 -2 +0 -1 $SORTTMP \
  198.   | awk "-F$tabch" 'BEGIN{tabch="'"$tabch"'"; lowcount='"$lowcount"'}
  199.     if ($1 == last1  &&  $2 == last2)
  200.         {
  201.         count++
  202.         totchars += $3
  203.         }
  204.     else
  205.         {
  206.         if ((last1 != ""  ||  last2 != "")  &&  count >= lowcount)
  207.         print last1 tabch last2 tabch count tabch totchars
  208.         count = 1
  209.         last1 = $1
  210.         last2 = $2
  211.         totchars = $3
  212.         }
  213.     END {
  214.     if ((last1 != ""  ||  last2 != "")  &&  count >= lowcount)
  215.         print last1 tabch last2 tabch count tabch totchars
  216.     }' \
  217.   | sort "-t$tabch" $finalsortopts $SORTTMP \
  218.   | if [ "$cleanout" = "yes" ]
  219.     then
  220.     case "$tabch" in
  221.         /)
  222.         sedsub=/
  223.         sedsep=';'
  224.         .|\*|\[|\^|\$|\\)
  225.         sedsub="\\$tabch"
  226.         sedsep=/
  227.         *)
  228.         sedsub="$tabch"
  229.         sedsep=/
  230.     esac
  231.     exec sed -e "s$sedsep$sedsub$sedsep    ${sedsep}g" \
  232.       -e 's/    /+/' -e 's/^/-/' \
  233.       -e 's/^-+/+/' -e 's/+    /    /'
  234.     else
  235.     exec cat
  236.     fi
  237. /bin/rm -f ${TMP}?
  238.